package bu.met.cs664;

import java.util.EnumSet;

/**
 * Created by mcox on 9/18/14.
 */
public class BoardEvaluator {
    public static final EnumSet<BoardWinConfigurations> winConfigurations = EnumSet.allOf(BoardWinConfigurations.class);
    public static final int VICTORY_IMMINENT = 1000;
    public static final int VICTORY_GUARANTEED = 10000;
    public static final int NEUTRAL = 0;
    public static final int LOSS_IMMINENT = -1000;
    public static final int LOSS_GUARANTEED = -10000;
    public static final char SPACE = ' ';

    private char playerSymbol;
    private char opponentSymbol;

    public BoardEvaluator(char playerSymbol, char opponentSymbol) {
        this.playerSymbol = playerSymbol;
        this.opponentSymbol = opponentSymbol;
    }

    public int evaluate(char [] board) {
        if (board.length != 9) {
            throw new IllegalArgumentException("Invalid board size");
        }

        int finalScore = 0;

        for (BoardWinConfigurations winConfig : winConfigurations) {
            finalScore += evaluateWinConfiguration(winConfig, board);
        }

        return finalScore;
    }

    private int evaluateWinConfiguration(BoardWinConfigurations winConfiguration, char [] board) {
        int playerOwned = countOwned(winConfiguration, board, playerSymbol);
        int opponentOwned = countOwned(winConfiguration, board, opponentSymbol);

        if (playerOwned == 3) {
            return VICTORY_GUARANTEED;
        } else if (playerOwned == 2) {
            return VICTORY_IMMINENT;
        } else if (opponentOwned == 3) {
            return LOSS_GUARANTEED;
        } else if (opponentOwned == 2) {
            return LOSS_IMMINENT;
        }

        return NEUTRAL;
    }

    private int countOwned(BoardWinConfigurations winConfiguration, char [] board, char symbol) {
        int count = 0;

        for (int square : winConfiguration.getSquares()) {
            if (board[square] == symbol) {
                count++;
            } else if (board[square] != SPACE) {
                count--;
            }
        }

        return count;
    }

    public static void main(String [] main) {
        final char X = 'X';
        final char O = 'O';
        final char S = ' ';
        BoardEvaluator evaluator = new BoardEvaluator(X, O);
        assert evaluator.evaluate(new char [] {S, S, S, S, S, S, S ,S ,S}) == 0;
        assert evaluator.evaluate(new char [] {X, S, S, S, S, S, S, S, S}) == 0;
        assert evaluator.evaluate(new char [] {X, X, S, O, S, S, S, S, S}) == 1000;
        assert evaluator.evaluate(new char [] {X, S, X, O, S, S, S, S, S}) == 1000;
        assert evaluator.evaluate(new char [] {X, X, X, O, O, S, S, S, S}) == 9000;
        assert evaluator.evaluate(new char [] {X, X, X, O, S, O, S, S, S}) == 9000;
        assert evaluator.evaluate(new char [] {X, X, X, O, S, S, O, S, S}) == 10000;
    }
}

